/**  
 * Copyrights@2006, Tianyuan DIC Information Co.,Ltd.
 * 文件名:    TMallPayHandle.java  
 * 描述:   
 * 作者:     kaiyang
 * 版本:    1.0  
 * 创建时间:   2015年5月4日 上午11:57:29  
 *  
 * 修改历史:  
 * 日期                          作者           版本         描述  
 * ------------------------------------------------------------------  
 * 2015年5月4日      kaiyang      1.0        1.0 Version  
 */ 
package com.hp.bon.sgw.wh.channel.handler;

import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.xml.stream.XMLInputFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import com.hp.bon.sgw.Constants;
import com.hp.bon.sgw.Constants.MessageType;
import com.hp.bon.sgw.bean.XmlMessage;
import com.hp.bon.sgw.core.BuzProcessorManager;
import com.hp.bon.sgw.core.CallParam;
import com.hp.bon.sgw.core.channel.SoapChannel;
import com.hp.bon.sgw.core.channel.handler.IAsynCallHandler;
import com.hp.bon.sgw.domain.MessageDetail;
import com.hp.bon.sgw.start.SpringContext;
import com.hp.bon.sgw.threads.MessageDetailCacheManager;
import com.hp.bon.sgw.threads.TaskManager;
import com.hp.bon.sgw.wh.bean.BillListQuery;
import com.hp.bon.sgw.wh.service.TMallResponseService;
import com.hp.bon.sgw.wh.service.TmallLogDao;
import com.hp.bon.sgw.wh.util.DateUtil;
import com.hp.ocs.diameter.message.AVP;
import com.hp.ocs.diameter.message.AVP_Grouped;
import com.hp.ocs.diameter.message.AVP_Integer64;
import com.hp.ocs.diameter.message.AVP_UTF8String;
import com.hp.ocs.diameter.message.AVP_Unsigned32;
import com.hp.ocs.diameter.message.Message;

/**  
 * @ClassName: TMallPayHandle   
 * @author: wanghan  
 * @date:2017年2月16日 上午11:57:29     
 */
public class BillListQueryHandler implements IAsynCallHandler{

	private static final Logger _log = LoggerFactory.getLogger(TaobaoFeeHandle.class);
	private PrintStream printStream;
	private Map<String, Object> data =new HashMap<String, Object>();
	private TMallResponseService tmallResponseService;
	private ThreadPoolTaskExecutor asynExecutor;
	TmallLogDao tmallLogDao=(TmallLogDao)SpringContext.getInstance().getApplicationContext().getBean("tmallLogDao");
	static XMLInputFactory inputFactory = XMLInputFactory.newInstance();
	private static Map<String, String> areacode =new HashMap<String, String>();
	private static Map<String, String> qhmap =new HashMap<String, String>();
	
	static{
		areacode.put("0271001","1001");
		areacode.put("07101003","1003");
		areacode.put("07131004","1004");
		areacode.put("07171005","1005");
		areacode.put("07121006","1006");
		areacode.put("07121007","1007");
		areacode.put("07151008","1008");
		areacode.put("07191009","1009");
		areacode.put("07241010","1010");
		areacode.put("07141011","1011");
		areacode.put("07221012","1012");
		areacode.put("07181013","1013");
		areacode.put("07281014","1014");
		areacode.put("07281015","1015");
		areacode.put("07281016","1016");
		areacode.put("07191017","1017");
		areacode.put("07161018","1018");
		
		qhmap.put("027","1");
		qhmap.put("0710","1");
		qhmap.put("0713","1");
		qhmap.put("0717","1");
		qhmap.put("0712","1");
		qhmap.put("0712","1");
		qhmap.put("0715","1");
		qhmap.put("0719","1");
		qhmap.put("0724","1");
		qhmap.put("0714","1");
		qhmap.put("0722","1");
		qhmap.put("0718","1");
		qhmap.put("0728","1");
		qhmap.put("0719","1");
		qhmap.put("0716","1");
	}
	public BillListQueryHandler(PrintStream printStream, Map<String, Object> data,
			TMallResponseService tmallResponseService,
			ThreadPoolTaskExecutor asynExecutor) {
		this.printStream = printStream;
        this.tmallResponseService = tmallResponseService;
        this.asynExecutor = asynExecutor;
        this.data = data;
	}

	@Override
	public int getProtocolType() {
		
		return 0;
	}
  
	@Override
	public void onCallResult(CallParam callParam) {
		XmlMessage ack = null;
		Object response = null;
		if (callParam.getResponse() != null) {
			response = callParam.getResponse();
		} else if (callParam.getRecvResponse() != null) {
			response = callParam.getRecvResponse();
		}
		if (response == null) {
			ack = SoapChannel.createERRAnwser(
					callParam.getSessionId(),
					callParam.getRetCode() == 3002 ? 11202 : callParam
							.getRetCode(), callParam.getResultMsg());
		} else {
			if (response instanceof Message) {// CCA -> XML
				ack = BuzProcessorManager.getInstance().convertMessageToAck(
						callParam);
			} else if (response instanceof XmlMessage) {
				ack = (XmlMessage) response;
			} else {
				_log.warn("unknown response type:"
						+ callParam.getResponse().getClass().getName());
			}
		}
		try {
			
			_log.info("CCA 返回信息");
			
			String respXML = convertResponseString((Message)response,callParam.getServiceResultCode());
			
			_log.info("respXML 响应信息："+respXML);
			
			byte[] resp = respXML.getBytes("UTF-8");
			ack.setLength(resp.length);
			ack.setMsgTime(System.currentTimeMillis());
			printStream.write(resp);
			printStream.close();

			callParam.setResponse(ack);

			if (callParam.getRetCode() == Constants.ResultCode.SUCCESS) {// 成功的消息，请求应答入库

				MessageDetail detail = new MessageDetail();
				detail.setBusinessCallId(callParam.getBussinessCallId());
				detail.setSessionId(callParam.getSessionId());
				detail.setServiceContextId(callParam.getServiceContextId());
				detail.setMessageType(MessageType.WSA);
				detail.setDetails(ack.getDATA());
				detail.setMsgTime(new Date(ack.getMsgTime()));
				detail.setOpType("send");
				detail.setHostId(callParam.getUserName());
				MessageDetailCacheManager.getInstance().add(detail);
			}
			TaskManager.taskProcess(callParam);
		} catch (Exception e) {
			 _log.info("Exception:"+e);
			e.printStackTrace();
		}
	}


	private String convertResponseString(Message answer, int serviceResultCode) throws Exception
	{
		
		_log.info("ConvertResponseString start");
		String response = "";	    	
		_log.info("serviceResultCode："+serviceResultCode);
		if (serviceResultCode == 0)   //充值成功
		{
			AVP avp = answer.find(Constants.DIAMETER_AVP_SERVICE_INFOMATION,Constants.DIAMETER_VENDOR_3GPP);
		    AVP_Grouped avpServiceInfomation = new AVP_Grouped(avp);
		    
		    AVP Data_InformationAvp = avpServiceInfomation.find(80700,Constants.DIAMETER_VENDOR_CT);
		    AVP_Grouped avpBill_Information = new AVP_Grouped(Data_InformationAvp);
		    
		    long total_Charge =0L;
		    AVP total_ChargeAvp = avpBill_Information.find(80141,Constants.DIAMETER_VENDOR_CT);
		    if (total_ChargeAvp != null){
		    	total_Charge =new AVP_Integer64(total_ChargeAvp).queryValue();
		    }
		    _log.info("total_Charge:"+total_Charge);
		    
		    long chargePayed =0L;
		    AVP chargePayedAvp = avpBill_Information.find(90203,Constants.DIAMETER_VENDOR_CT);
		    if (chargePayedAvp != null){
		    	chargePayed =new AVP_Integer64(chargePayedAvp).queryValue();
		    }
		    _log.info("chargePayed:"+chargePayed);
		    long chargeShouldpay =0L;
		    AVP ChargeShouldpayAvp = avpBill_Information.find(90223,Constants.DIAMETER_VENDOR_CT);
		    if (ChargeShouldpayAvp != null){
		    	chargeShouldpay =new AVP_Integer64(ChargeShouldpayAvp).queryValue();
		    }
		    _log.info("chargeShouldpay:"+chargeShouldpay);
		    long chargeFreeDiscount =0L;
		    AVP chargeFreeDiscountAvp = avpBill_Information.find(90224,Constants.DIAMETER_VENDOR_CT);
		    if (chargeFreeDiscountAvp != null){
		    	chargeFreeDiscount =new AVP_Integer64(chargeFreeDiscountAvp).queryValue();
		    }
		    long chargeCorpusDiscount =0L;
		    AVP chargeCorpusDiscountAvp = avpBill_Information.find(90225,Constants.DIAMETER_VENDOR_CT);
		    if (chargeCorpusDiscountAvp != null){
		    	chargeCorpusDiscount =new AVP_Integer64(chargeCorpusDiscountAvp).queryValue();
		    }
		    _log.info("chargeCorpusDiscount:"+chargeCorpusDiscount);
		    String acct_Name ="";
		    AVP acct_NameAvp = avpBill_Information.find(80108,Constants.DIAMETER_VENDOR_CT);
		    if (acct_NameAvp != null){
		    	acct_Name =new AVP_UTF8String(acct_NameAvp).queryValue();
		    }
		    _log.info("acct_Name:"+acct_Name);
		    String accNbrDetai2 ="";
		    AVP accNbrDetaiAvp = avpBill_Information.find(90226,Constants.DIAMETER_VENDOR_CT);
		    if (accNbrDetaiAvp != null){
		    	accNbrDetai2 =new AVP_UTF8String(accNbrDetaiAvp).queryValue();
		    }
		    _log.info("accNbrDetai2:"+accNbrDetai2);
		    
		    
		    
		    
		    List<AVP>  list  =new ArrayList<AVP>();
		    
			AVP[] avps = avpBill_Information.queryAVPs();
			for (AVP avpType : avps)
			{
				if (avpType.code() == 81170 && avpType.vendorID() == Constants.DIAMETER_VENDOR_CT){
					_log.info("avpType.code():"+avpType.code());
					list.add(avpType);
				}
			}
		    
			StringBuffer sb =new StringBuffer();
			sb.append("<?xml version='1.0' encoding='UTF-8'?>");
			sb.append("<ContractRoot>");
			sb.append("<TcpCont>");
			sb.append("<ActionCode>1</ActionCode>");
			sb.append("<TransactionID>"+data.get("TransactionID").toString()+"</TransactionID>");
			sb.append("<RspTime>"+DateUtil.dateTimeToStr(new Date())+"</RspTime>");
			sb.append("<Response>");
			sb.append("<RspType>0</RspType>");
			sb.append("<RspCode>0000</RspCode>");
			sb.append("<RspDesc>成功</RspDesc>");
			sb.append("</Response>");
			sb.append("</TcpCont>");
			sb.append("<SvcCont>");
			sb.append("<QryInfoRsp>");
			sb.append("<InfoTypeID>15</InfoTypeID> ");
			sb.append("<BillInfo>");
			sb.append("<ChargeAll>"+total_Charge+"</ChargeAll> ");
			sb.append("<ChargePaid>"+chargePayed+"</ChargePaid> ");
			sb.append("<ChargeShouldpay>"+chargeShouldpay+"</ChargeShouldpay> ");
			sb.append("<ChargeDiscount>"+(chargeFreeDiscount+chargeCorpusDiscount)+"</ChargeDiscount>");
			sb.append("<ChargeAccountInfo>"+accNbrDetai2+"</ChargeAccountInfo> ");
			sb.append("<AcctName>"+acct_Name+"</AcctName> ");
			
			AVP Item_InformationAvp =null;
			AVP_Grouped avpItem_InformationAvp=null;
			AVP showlevelAvp,product_OFF_NameAvp,class_IdAvp,parent_Class_IdAvp,charge_type_NameAvp,chargeAvp,accNbrDetaiAvp3=null;
			int showlevel=0;
			int class_Id=0;
			int parent_Class_Id=0;
			String product_OFF_Name ="";
			String charge_type_Name ="";
			long charge =0L;
			String accNbrDetai3 ="";
			
			BillListQuery billListQuery =null;
			LinkedList<BillListQuery>  listQueries =new LinkedList<BillListQuery>();
			for (int i = 0; i < list.size(); i++) {
				
				Item_InformationAvp =list.get(i);
			    avpItem_InformationAvp = new AVP_Grouped(Item_InformationAvp);
			    
			    
			    showlevelAvp = avpItem_InformationAvp.find(80328,Constants.DIAMETER_VENDOR_CT);
			    if (showlevelAvp != null){
			    	showlevel =new AVP_Unsigned32(showlevelAvp).queryValue();
			    }
			    _log.info("showlevel:"+showlevel);
			    
			    if(showlevel==1){
					continue;
				}else{
					
					charge_type_NameAvp = avpItem_InformationAvp.find(80322,Constants.DIAMETER_VENDOR_CT);
				    if (charge_type_NameAvp != null){
				    	charge_type_Name =new AVP_UTF8String(charge_type_NameAvp).queryValue();
				    	
				    }
				    _log.info("charge_type_Name:"+charge_type_Name);
				    
					if(showlevel==2 && ("本项小计".equals(charge_type_Name)
							||charge_type_Name.contains(":")
							||"套餐超出费用".equals(charge_type_Name))){
						continue;
					}
					
					billListQuery=new BillListQuery();
					billListQuery.setCharge_type_Name(charge_type_Name);
					billListQuery.setShowlevel(showlevel);
					
					product_OFF_NameAvp = avpItem_InformationAvp.find(80176,Constants.DIAMETER_VENDOR_CT);
				    if (product_OFF_NameAvp != null){
				    	product_OFF_Name =new AVP_UTF8String(product_OFF_NameAvp).queryValue();
				    	billListQuery.setProduct_OFF_Name(product_OFF_Name);
				    }
				    _log.info("product_OFF_Name:"+product_OFF_Name);
				    
				    class_IdAvp = avpItem_InformationAvp.find(80441,Constants.DIAMETER_VENDOR_CT);
				    if (class_IdAvp != null){
				    	class_Id =new AVP_Unsigned32(class_IdAvp).queryValue();
				    	billListQuery.setClass_Id(class_Id);
				    }
				    _log.info("class_Id:"+class_Id);
				   
				    parent_Class_IdAvp = avpItem_InformationAvp.find(80443,Constants.DIAMETER_VENDOR_CT);
				    if (parent_Class_IdAvp != null){
				    	parent_Class_Id =new AVP_Unsigned32(parent_Class_IdAvp).queryValue();
				    	billListQuery.setParent_Class_Id(parent_Class_Id);
				    }
				    _log.info("parent_Class_Id:"+parent_Class_Id);
				    
				    chargeAvp = avpItem_InformationAvp.find(81171,Constants.DIAMETER_VENDOR_CT);
				    if (chargeAvp != null){
				    	charge =new AVP_Integer64(chargeAvp).queryValue();
				    	billListQuery.setCharge(charge);
				    }
				    _log.info("charge:"+charge);
				    
				    accNbrDetaiAvp3 = avpItem_InformationAvp.find(90226,Constants.DIAMETER_VENDOR_CT);
				    if (accNbrDetaiAvp3 != null){
				    	accNbrDetai3 =new AVP_UTF8String(accNbrDetaiAvp3).queryValue();
				    	billListQuery.setAccNbrDetai3(accNbrDetai3);
				    }
				    _log.info("accNbrDetai3:"+accNbrDetai3);
				    listQueries.add(billListQuery);
				}
			  }
			
			int classId=10001;
			BillListQuery bill=null;
			int classId4=0;
			String charge_type_Name3 ="";
			int chargetypeName3=0;
			_log.info("listQueries size:"+listQueries.size());
			for (int i = 0; i < listQueries.size(); i++) {
				billListQuery=listQueries.get(i);
				if(billListQuery.getShowlevel()==2){
					sb.append("<BillItemInfo>");
					_log.info("Showlevel:2");
					sb.append("<ClassId>"+classId+"</ClassId> ");
					sb.append("<ParentClassId>0</ParentClassId> ");
					sb.append("<Showlevel>1</Showlevel> ");
					sb.append("<AccountMobile>"+billListQuery.getAccNbrDetai3()+"</AccountMobile> ");
					sb.append("<ChargeDisname>"+billListQuery.getProduct_OFF_Name()+"</ChargeDisname> ");
					classId++;
				}else if(billListQuery.getShowlevel()==3){
					_log.info("Showlevel:3");
					if(billListQuery.getCharge_type_Name().contains(":")){
						charge_type_Name3=billListQuery.getCharge_type_Name();
						chargetypeName3=1;
						continue;
					}else{
						chargetypeName3=0;
					}
					sb.append("<BillItemInfo>");
					if((i+1)<listQueries.size()){
						bill=listQueries.get(i+1);
						if(bill!=null&&bill.getShowlevel()==4){
							sb.append("<ClassId>"+classId+"</ClassId> ");
							sb.append("<ParentClassId>0</ParentClassId> ");
							sb.append("<Showlevel>1</Showlevel> ");
							sb.append("<AccountMobile>"+billListQuery.getAccNbrDetai3()+"</AccountMobile> ");
							sb.append("<ChargeDisname>"+billListQuery.getProduct_OFF_Name()+"</ChargeDisname> ");
						}else{
							sb.append("<ClassId>"+classId+"</ClassId> ");
							sb.append("<ParentClassId>"+(classId-1)+"</ParentClassId> ");
							sb.append("<Showlevel>2</Showlevel> ");
						}
					}else{
						sb.append("<ClassId>"+classId+"</ClassId> ");
						sb.append("<ParentClassId>"+(classId-1)+"</ParentClassId> ");
						sb.append("<Showlevel>2</Showlevel> ");
					}
					classId++;
				}else if(billListQuery.getShowlevel()==4){
					sb.append("<BillItemInfo>");
					sb.append("<ClassId>"+classId+"</ClassId> ");
					sb.append("<ParentClassId>0</ParentClassId> ");
					sb.append("<Showlevel>1</Showlevel> ");
					sb.append("<ChargeDisname>"+billListQuery.getProduct_OFF_Name()+"</ChargeDisname> ");
					if(chargetypeName3==1){
						sb.append("<AccountMobile>"+charge_type_Name3+"</AccountMobile> ");
					}else{
						sb.append("<AccountMobile>"+billListQuery.getAccNbrDetai3()+"</AccountMobile> ");
					}
					
					if((i+1)<listQueries.size()){
						bill=listQueries.get(i+1);
						if(bill!=null&&bill.getShowlevel()==5){
							classId4=classId;
						}
					}
					classId++;
				}else if(billListQuery.getShowlevel()==5){
					sb.append("<BillItemInfo>");
					sb.append("<ClassId>"+classId+"</ClassId> ");
					sb.append("<ParentClassId>"+classId4+"</ParentClassId> ");
					sb.append("<Showlevel>2</Showlevel> ");
					classId++;
				}
				
				sb.append("<ChargeName>"+billListQuery.getCharge_type_Name()+"</ChargeName> ");
				sb.append("<Charge>"+billListQuery.getCharge()+"</Charge>");
				sb.append("</BillItemInfo> ");
			}
			
			sb.append("</BillInfo>");
			sb.append("</QryInfoRsp>");
			sb.append("</SvcCont>"); 
			sb.append("</ContractRoot>");
			_log.info("========response========" + sb.toString());
			response=sb.toString();
			
		}else{
			return returnXml(data.get("TransactionID").toString(), "1005", "缺失账户信息");
		}
		return response;
	}
	
	
	/**
	 * 返回报文
	 */
	
	public static String returnXml(String TransactionID,String RspCode,String RspDesc){
		StringBuffer sb =new StringBuffer();
		sb.append("<?xml version='1.0' encoding='UTF-8'?>");
		sb.append("<ContractRoot>");
		sb.append("<TcpCont>");
		sb.append("<ActionCode>1</ActionCode>");
		sb.append("<TransactionID>"+TransactionID+"</TransactionID>");
		sb.append("<RspTime>"+DateUtil.dateTimeToStr(new Date())+"</RspTime>");
		sb.append("<Response>");
		sb.append("<RspType>1</RspType>");
		sb.append("<RspCode>"+RspCode+"</RspCode>");
		sb.append("<RspDesc>"+RspDesc+"</RspDesc>");
		sb.append("</Response>");
		sb.append("</TcpCont>");
		sb.append("</ContractRoot>");
		return sb.toString();
	}
}
